/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * FPdfMerge.java
 *
 * Created on May 11, 2009, 1:20:30 PM
 */
package pdfmerge;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfCopyFields;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Set;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.ini4j.Profile.Section;
import org.ini4j.Wini;

/**
 *
 * @author FLAVIO.REIS
 */
public class FPdfMerge extends javax.swing.JFrame {

    private DefaultListModel flModel = new DefaultListModel();
    private LinkedList<JComponent> pnComponents = new LinkedList<JComponent>();
    private Wini iniFile;

    /** Creates new form FPdfMerge */
    public FPdfMerge() {
        initComponents();
        lFiles.setModel(flModel);

        pnComponents.add(tFromPage);
        pnComponents.add(tInitialPageNumber);
        pnComponents.add(tHorizontalMargin);
        pnComponents.add(tVerticalMargin);
        pnComponents.add(cbPosition);
        pnComponents.add(tMask);
        pnComponents.add(tFontSize);
        pnComponents.add(cbFontName);

        DefaultComboBoxModel cbModel = new DefaultComboBoxModel();
        cbModel.addElement("Courier");
        cbModel.addElement("Courier-Bold");
        cbModel.addElement("Courier-Oblique");
        cbModel.addElement("Courier-BoldOblique");
        cbModel.addElement("Helvetica");
        cbModel.addElement("Helvetica-Bold");
        cbModel.addElement("Helvetica-Oblique");
        cbModel.addElement("Helvetica-BoldOblique");
        cbModel.addElement("Times-Roman");
        cbModel.addElement("Times-Bold");
        cbModel.addElement("Times-Italic");
        cbModel.addElement("Times-BoldItalic");
        cbFontName.setModel(cbModel);

        loadSetups();
        loadDefaultSetup();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mSave = new javax.swing.JPopupMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        bMerge = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        lFiles = new javax.swing.JList();
        bAdd = new javax.swing.JButton();
        tMergeTo = new javax.swing.JTextField();
        bSelect = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        chNumbering = new javax.swing.JCheckBox();
        jLabel10 = new javax.swing.JLabel();
        tMask = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        tInitialPageNumber = new javax.swing.JSpinner();
        jLabel3 = new javax.swing.JLabel();
        tFromPage = new javax.swing.JSpinner();
        jLabel5 = new javax.swing.JLabel();
        cbPosition = new javax.swing.JComboBox();
        jLabel6 = new javax.swing.JLabel();
        tHorizontalMargin = new javax.swing.JSpinner();
        jLabel7 = new javax.swing.JLabel();
        tVerticalMargin = new javax.swing.JSpinner();
        jLabel8 = new javax.swing.JLabel();
        tFontSize = new javax.swing.JSpinner();
        jLabel9 = new javax.swing.JLabel();
        cbFontName = new javax.swing.JComboBox();
        jLabel11 = new javax.swing.JLabel();
        bSaveSetup = new javax.swing.JButton();
        lSection = new javax.swing.JLabel();

        jMenuItem1.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
        jMenuItem1.setText("Save setup");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        mSave.add(jMenuItem1);

        jMenuItem2.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
        jMenuItem2.setText("New Setup");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        mSave.add(jMenuItem2);

        jMenuItem3.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
        jMenuItem3.setText("Remove Setup");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        mSave.add(jMenuItem3);
        mSave.add(jSeparator1);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("SUTEC PDF Merge Tool");

        bMerge.setText("Merge");
        bMerge.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bMergeActionPerformed(evt);
            }
        });

        lFiles.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                lFilesKeyReleased(evt);
            }
        });
        jScrollPane1.setViewportView(lFiles);

        bAdd.setText("Add File(s) to Merge List");
        bAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bAddActionPerformed(evt);
            }
        });

        tMergeTo.setEditable(false);

        bSelect.setText("Select");
        bSelect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bSelectActionPerformed(evt);
            }
        });

        jLabel1.setText("Merge to:");

        jLabel4.setFont(new java.awt.Font("Tahoma", 2, 11));
        jLabel4.setText("Press DEL to remove selected(s)");

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Page Numbering"));

        chNumbering.setSelected(true);
        chNumbering.setText("Paging");
        chNumbering.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                chNumberingStateChanged(evt);
            }
        });

        jLabel10.setText("Mask:");

        tMask.setText("Página [x] de [y]");

        jLabel2.setText("Initial page number:");

        tInitialPageNumber.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(1), Integer.valueOf(1), null, Integer.valueOf(1)));

        jLabel3.setText("From page:");

        tFromPage.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(1), Integer.valueOf(1), null, Integer.valueOf(1)));

        jLabel5.setText("Position:");

        cbPosition.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Top Left", "Top Right", "Bottom Left", "Bottom Right" }));

        jLabel6.setText("Horizontal Margin:");

        tHorizontalMargin.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(10), Integer.valueOf(0), null, Integer.valueOf(1)));

        jLabel7.setText("Vertical Margin:");

        tVerticalMargin.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(10), Integer.valueOf(0), null, Integer.valueOf(1)));

        jLabel8.setText("Font Size:");

        tFontSize.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(8), Integer.valueOf(4), null, Integer.valueOf(1)));

        jLabel9.setText("Font Name:");

        jLabel11.setFont(new java.awt.Font("Tahoma", 2, 11));
        jLabel11.setText("[x] page number, [y] total of pages");

        bSaveSetup.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
        bSaveSetup.setText("...");
        bSaveSetup.setToolTipText("Save setup");
        bSaveSetup.setMargin(new java.awt.Insets(2, 4, 2, 4));
        bSaveSetup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bSaveSetupActionPerformed(evt);
            }
        });

        lSection.setForeground(javax.swing.UIManager.getDefaults().getColor("textHighlight"));
        lSection.setText("Default");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel5)
                            .addComponent(jLabel6)
                            .addComponent(jLabel7)
                            .addComponent(jLabel8)
                            .addComponent(jLabel9)
                            .addComponent(jLabel10)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(chNumbering)))
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(tFontSize, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(tVerticalMargin, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(tHorizontalMargin, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                                .addComponent(tMask, javax.swing.GroupLayout.DEFAULT_SIZE, 214, Short.MAX_VALUE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel11))
                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(cbFontName, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(cbPosition, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                                    .addComponent(tInitialPageNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(18, 18, 18)
                                    .addComponent(jLabel3)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(tFromPage, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE))))
                        .addContainerGap())
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(309, 309, 309)
                        .addComponent(lSection)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bSaveSetup))))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(chNumbering))
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(bSaveSetup)
                        .addComponent(lSection)))
                .addGap(7, 7, 7)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tMask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10)
                    .addComponent(jLabel11))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(tInitialPageNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)
                    .addComponent(tFromPage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(cbPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(tHorizontalMargin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(tVerticalMargin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(tFontSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(cbFontName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(16, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(20, 20, 20)
                        .addComponent(bAdd)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 280, Short.MAX_VALUE)
                        .addComponent(jLabel4))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bMerge))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(20, 20, 20)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 584, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel1)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(tMergeTo, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(bSelect)))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(bAdd)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tMergeTo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(bSelect)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(bMerge)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void bMergeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bMergeActionPerformed
        try {
            if (flModel.size() < 1) {
                JOptionPane.showMessageDialog(this, "Add file(s) to merge list.");
                return;
            }

            if (tMergeTo.getText().isEmpty()) {
                JOptionPane.showMessageDialog(this, "Select [Merge to] file.");
                return;
            }

            File tmpFile = File.createTempFile("PDFMergeTools", "pdf");

            PdfCopyFields copy = new PdfCopyFields(new FileOutputStream(tmpFile));

            for (Object fileName : flModel.toArray()) {
                PdfReader pdfFile = new PdfReader((String) fileName);
                copy.addDocument(pdfFile);
                pdfFile.close();
            }

            copy.close();

            // Rotina para numeração de páginas
            if (chNumbering.isSelected()) {

                PdfReader reader = new PdfReader(tmpFile.getAbsolutePath());
                int n = reader.getNumberOfPages();

                PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tMergeTo.getText()));
                PdfContentByte over;
                String fontName = cbFontName.getSelectedItem().toString();
                BaseFont bf = BaseFont.createFont(fontName, BaseFont.WINANSI, BaseFont.EMBEDDED);

                int initialPageNumber = Integer.parseInt(tInitialPageNumber.getModel().getValue().toString());
                int fromPage = Integer.parseInt(tFromPage.getModel().getValue().toString());
                int horizontalMargin = Integer.parseInt(tHorizontalMargin.getModel().getValue().toString());
                int verticalMargin = Integer.parseInt(tVerticalMargin.getModel().getValue().toString());
                String position = cbPosition.getSelectedItem().toString();
                int align = PdfContentByte.ALIGN_LEFT;
                int fontSize = Integer.parseInt(tFontSize.getModel().getValue().toString());
                String mask = tMask.getText();

                for (int i = 1; i <= n; i++) {
                    if (i >= fromPage) {
                        over = stamper.getOverContent(i);
                        over.beginText();
                        over.setFontAndSize(bf, fontSize);
                        float width = stamper.getImportedPage(reader, i).getWidth();
                        float height = stamper.getImportedPage(reader, i).getHeight();

                        String chunk = mask.replace("[x]", String.valueOf(i + initialPageNumber - 1));
                        chunk = chunk.replace("[y]", String.valueOf(n));
                        //chunk = String.format("Página %d de %d", , n);
                        //float textSize = over.getEffectiveStringWidth(chunk, true);

                        float x = width;
                        float y = height;

                        if (position.endsWith("Left")) {
                            x = horizontalMargin;
                            align = PdfContentByte.ALIGN_LEFT;
                        } else {
                            //x = width - textSize - horizontalMargin;
                            x = width - horizontalMargin;
                            align = PdfContentByte.ALIGN_RIGHT;
                        }
                        if (position.startsWith("Bottom")) {
                            y = verticalMargin;
                        } else {
                            y = height - verticalMargin - fontSize;
                        }

                        over.showTextAligned(align, chunk, x, y, 0);

                        over.endText();
                    }
                }

                stamper.close();
                reader.close();
            }

            JOptionPane.showMessageDialog(this, "Merge completed!");

        } catch (DocumentException ex) {
            JOptionPane.showMessageDialog(this, ex.getLocalizedMessage());
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(this, ex.getLocalizedMessage());
        }
    }//GEN-LAST:event_bMergeActionPerformed

    private void bAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bAddActionPerformed
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter fnef = new FileNameExtensionFilter("PDF", "pdf");
        chooser.setFileFilter(fnef);
        chooser.setDialogTitle("Select PDF file(s)");
        chooser.setDialogType(JFileChooser.OPEN_DIALOG);
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        chooser.setMultiSelectionEnabled(true);

        int result = chooser.showOpenDialog(this);

        if (result == JFileChooser.APPROVE_OPTION) {
            File[] files = chooser.getSelectedFiles();

            for (File file : files) {
                flModel.addElement(file.getAbsolutePath());
            }

            lFiles.setModel(flModel);

        }
    }//GEN-LAST:event_bAddActionPerformed

    private void lFilesKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_lFilesKeyReleased
        if (evt.getKeyCode() == 127) { //DEL

            int count = 0;
            for (int index : lFiles.getSelectedIndices()) {
                flModel.remove(index - count++);
            }
        }

    }//GEN-LAST:event_lFilesKeyReleased

    private void bSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bSelectActionPerformed
        JFileChooser chooser = new JFileChooser();
        chooser.setDialogType(JFileChooser.SAVE_DIALOG);
        FileNameExtensionFilter fnef = new FileNameExtensionFilter("PDF", "pdf");
        chooser.setFileFilter(fnef);

        boolean showDialog = true;
        while (showDialog) {
            int result = chooser.showSaveDialog(this);

            if (result == JFileChooser.APPROVE_OPTION) {
                File saveTo = chooser.getSelectedFile();

                if (saveTo.exists()) {
                    JOptionPane.showMessageDialog(this, "This file already exists. Try another.");
                    tMergeTo.setText("");
                } else {
                    tMergeTo.setText(saveTo.getAbsolutePath());
                    showDialog = false;
                }
            } else {
                showDialog = false;
            }
        }

    }//GEN-LAST:event_bSelectActionPerformed

    private void chNumberingStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_chNumberingStateChanged
        for (JComponent c : pnComponents) {
            c.setEnabled(chNumbering.isSelected());
        }
    }//GEN-LAST:event_chNumberingStateChanged

    private void bSaveSetupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bSaveSetupActionPerformed
        mSave.show(bSaveSetup, 5, 5);
}//GEN-LAST:event_bSaveSetupActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        String setupName = JOptionPane.showInputDialog(this, "Setup name", "Setup Save", JOptionPane.QUESTION_MESSAGE);
        if (setupName != null) {
            saveSetup(setupName);
        }
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        saveSetup(lSection.getText());
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        String setupName = lSection.getText();
        
        if (setupName.equals("Default")) {
            JOptionPane.showMessageDialog(this, "Default setup cannot be removed.");
            return;
        }

        try {
            iniFile.remove(iniFile.get(setupName));
            iniFile.store();
            for (Component itemMenu : mSave.getComponents()) {
                if (itemMenu.getClass() == JMenuItem.class) {
                    JMenuItem obj = (JMenuItem) itemMenu;
                    if (lSection.getText().equals(obj.getName())) {
                        mSave.remove(itemMenu);
                        break;
                    }
                }
            }
            loadDefaultSetup();
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(this, "Error writing in setup.ini\n" + ex.getLocalizedMessage());
        }
    }//GEN-LAST:event_jMenuItem3ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new FPdfMerge().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bAdd;
    private javax.swing.JButton bMerge;
    private javax.swing.JButton bSaveSetup;
    private javax.swing.JButton bSelect;
    private javax.swing.JComboBox cbFontName;
    private javax.swing.JComboBox cbPosition;
    private javax.swing.JCheckBox chNumbering;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JList lFiles;
    private javax.swing.JLabel lSection;
    private javax.swing.JPopupMenu mSave;
    private javax.swing.JSpinner tFontSize;
    private javax.swing.JSpinner tFromPage;
    private javax.swing.JSpinner tHorizontalMargin;
    private javax.swing.JSpinner tInitialPageNumber;
    private javax.swing.JTextField tMask;
    private javax.swing.JTextField tMergeTo;
    private javax.swing.JSpinner tVerticalMargin;
    // End of variables declaration//GEN-END:variables

    private void saveSetup(String setupName) {
        try {
            String mask = tMask.getText();
            int initialPageNumber = Integer.parseInt(tInitialPageNumber.getModel().getValue().toString());
            int fromPage = Integer.parseInt(tFromPage.getModel().getValue().toString());
            String position = cbPosition.getSelectedItem().toString();
            int horizontalMargin = Integer.parseInt(tHorizontalMargin.getModel().getValue().toString());
            int verticalMargin = Integer.parseInt(tVerticalMargin.getModel().getValue().toString());
            int fontSize = Integer.parseInt(tFontSize.getModel().getValue().toString());
            String fontName = cbFontName.getSelectedItem().toString();
            iniFile.put(setupName, "mask", mask);
            iniFile.put(setupName, "initialPageNumber", initialPageNumber);
            iniFile.put(setupName, "fromPage", fromPage);
            iniFile.put(setupName, "position", position);
            iniFile.put(setupName, "horizontalMargin", horizontalMargin);
            iniFile.put(setupName, "verticalMargin", verticalMargin);
            iniFile.put(setupName, "fontSize", fontSize);
            iniFile.put(setupName, "fontName", fontName);
            iniFile.store();

            lSection.setText(setupName);
            JOptionPane.showMessageDialog(null, "Setup saved!");
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(this, "Error writing in setup.ini\n" + ex.getLocalizedMessage());
        }
    }

    private void loadSetups() {

        Properties p = new Properties();
        try {
            File fis = new File("setup.ini");
            if (!fis.exists()) {
                fis.createNewFile();
            }

            iniFile = new Wini(fis);
            Set<String> sections = iniFile.keySet();
            MenuItemListener menuItemListener = new MenuItemListener();

            for (String section : sections) {
                JMenuItem menuItem = mSave.add(section);
                menuItem.addActionListener(menuItemListener);
                menuItem.setName(section);
            }

        } catch (IOException ex) {
            JOptionPane.showMessageDialog(this, "Error reading or creating setup.ini\n" + ex.getLocalizedMessage());
            System.exit(-1);
        }

    }

    private void loadDefaultSetup() {
        Section sectionDefault = iniFile.get("Default");
        if (sectionDefault != null) {
            loadSetup(sectionDefault);
        } else {
            saveSetup("Default");
            loadSetups();
        }
    }

    private void loadSetup(Section section) {
        try {
            String mask = section.get("mask");
            int initialPageNumber = section.get("initialPageNumber", Integer.class);
            int fromPage = section.get("fromPage", Integer.class);
            String position = section.get("position");
            int horizontalMargin = section.get("horizontalMargin", Integer.class);
            int verticalMargin = section.get("verticalMargin", Integer.class);
            int fontSize = section.get("fontSize", Integer.class);
            String fontName = section.get("fontName");

            tMask.setText(mask);
            tInitialPageNumber.setValue(initialPageNumber);
            tFromPage.setValue(fromPage);
            cbPosition.setSelectedItem(position);
            tHorizontalMargin.setValue(horizontalMargin);
            tVerticalMargin.setValue(verticalMargin);
            tFontSize.setValue(fontSize);
            cbFontName.setSelectedItem(fontName);

            lSection.setText(section.getName());
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error reading setup " + section.getName() + " in setup.ini");
        }
    }

    private class MenuItemListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            String item = ((JMenuItem) e.getSource()).getName();

            if (item != null) {
                Section section = iniFile.get(item);
                loadSetup(section);
                JOptionPane.showMessageDialog(null, "Setup loaded!");
            }
        }
    }
}